#!/bin/bash
# Mojohost
# Script: mb_inst.sh
#
# Description: MechBunny Install Script
# Requires: Local MySQL, md5sum, run as root.
#
# Usage:
#     ./script.sh <domain> </path/to/doc/root> </path/to/mechbunny.zip>
#
# Example:
#     ./mb_inst.sh example.com /home/httpd/html/example.com/public_html /root/mechbunny.zip
#
# Instructions:
#     Provide values for the variables after this
#     comments section and run the script as shown
#     on the usage line above. It is written in this
#     to allow for iteration over multiple domains.
#
# Author: Gary Locke
#
# Changelog:
# * 4/17/2013 > Inital write
# - 4/18/2013 > Tested working
# - 4/20/2013
#     > MySQL username and database contain 4 random characters.
#     > Checks that the database name is unique, or else tries once more.
#     > Prints server line suitable for typical lighttpd config.
# - 4/23/2013
#     > Exits if document root is not empty.
# - 4/24/2013
#     > Asks for MySQL password if needed.
# - 6/5/2013
#     > Updated handling of MechBunny zip file.
#     > Added license option.
# - 6/20/2013
#     > Made compatible with old and new version of Mechbunny.
#
# Coming "soon":
#     Make sure paths to binaries are correct in admin/config.php
#     Support for remote database
#     Automatic update of lighttpd.conf
#

#################### INSTRUCTIONS ####################
#  Fill out the configuration below using absolute   #           
#  paths only, then run this script with the domain  #
#  name as the first argument, the absolute path to  #
#  the installation directory as the second, and the #
#    absolute path to the ZIP file as the third.     #
######################################################

#### START CONFIGURATION (OPTIONAL) ####

mb_sql=""        # Absolute path to SQL schema
mb_license=""    # MechBunny license key
admin_email=""   # Admin email account
admin_user=""    # Admin username (default: admin)
admin_pass=""    # Admin password (default: [random 8-char])
c_uid=""         # Local system UID (default: 500)

#### END CONFIGURATION ####


# Check for args.
if [[ -z "$1" || -z "$2" || -z "$3" ]];then
    echo -ne "\nFormat:\n./$0 domain /path/to/docroot /path/to/mechbunny.zip\n";exit 1
fi

# Remove trailing slashes from domain names.
domain=`echo $1|sed 's/\/$//'`
doc_root=`echo $2|sed 's/\/$//'`
mb_zip=$3

# Other variables.
date="$(date +"%s")"
dirName="$(dirname $doc_root)"
baseName="$(basename $doc_root)"
php_ini_path="$(php -i 2>&1 |awk '/^Loaded\ Configuration\ File/ {print $NF}')"

# Sanity checks.
if [[ `whoami` != "root" ]];then
    echo -ne "\nThis script must be run as root.\n"; exit 1
elif ! pgrep mysql >/dev/null; then
    echo -ne "\nThis script requires MySQL to be running locally.\n"; exit 1
elif ! which md5sum >/dev/null 2>&1;then
    echo -ne "\nThis script requires md5sum to be installed.\n"; exit 1
elif ! mysql -e ";" >/dev/null 2>&1; then
    read -e -p "Please enter MySQL root pass: " mysqlRootPass
    reqPass="-p$mysqlRootPass"
    if ! mysql $reqPass -e ";" >/dev/null 2>&1; then
        read -e -p "Password incorrect, please try again: " mysqlRootPass
        reqPass="-p$mysqlRootPass"
        if ! mysql $reqPass -e ";" >/dev/null 2>&1; then
            read -e -p "Password incorrect, please try again: " mysqlRootPass
            reqPass="-p$mysqlRootPass"
            if ! mysql $reqPass -e ";" >/dev/null 2>&1; then
            echo -ne "Password incorrect. Giving up.\n"; exit 1
            fi
        fi
    fi
fi


# Check if document root exists and exit if non-empty.
if [[ -d "$dirName" ]];then
    cd $dirName
else
    echo -ne "\"$dirName\" does not exist.\n"
    exit 1
fi

if [[ -d "$baseName" ]];then
    if [ "$(ls -A $baseName)" ];then
        echo -ne "Document root \"$doc_root\" must be empty to use this script. Please do something with the current site content and run this script again.\n"
        exit 1
    fi
else
    mkdir $baseName
fi

# Update permissions/ownership of document root.
[[ -z "$c_uid" ]] && c_uid=500
chown $c_uid.$c_uid $baseName
chmod 755 $baseName
cd $baseName

# Set unique MySQL credentials before beginning install.
mysqlNameGen () {
    uniqualizer=`cat /dev/urandom| tr -dc a-zA-Z0-9 | fold -w 4 |head -1`
    mysqlUser=`expr substr $domain 1 6|sed 's/\./_/g'|awk '{print $1"'$uniqualizer'_mb"}'`
    mysqlDb=$mysqlUser
    mysqlPass=`cat /dev/urandom| tr -dc a-zA-Z0-9 | fold -w 16 |head -1`
}

mysqlNameGen

# Check that user/database name is unique.
if mysql $reqPass -e "use $mysqlDb;" >/dev/null 2>&1;then
    mysqlNameGen # Trying again...
    if mysql $reqPass -e "use $mysqlDb;" >/dev/null 2>&1;then
        echo "Can't seem to find a unique database name. Please install manually."
        exit 1
    fi
fi

# Generate admin user and secure password if none specified in config.
[[ -z "$admin_user" ]] && admin_user="admin"
[[ -z "$admin_pass" ]] && admin_pass=`cat /dev/urandom| tr -dc a-zA-Z0-9 | fold -w 8 |head -1`



# Check that ZIP file exists.
while true;do
    if [[ -e "$mb_zip" ]];then
        break
    else
        read -e -p "\"$mb_zip\" not found. Enter absolute path to the mechbunny ZIP: " mb_zip
    fi
done

# Unzip zip file.
unzip -qq -P mb500 $mb_zip

# Get location of SQL schematic file.
getSqlSchema() {
    while true;do
        if [[ -e "$mb_sql" ]];then
            break
        else
            read -e -p "SQL schema not found. Enter valid path to schema file: " mb_sql
        fi
    done
}

# This bit handles versions differently.
if [[ -e "admin/config.php" ]];then
    if egrep -i '^\$license' admin/config.php;then
        licenced_version=1
        if [[ -e "schema.sql" ]];then
            mb_sql="schema.sql"
        else 
            getSqlSchema
        fi
    else
        getSqlSchema
    fi
elif [[ -e "*/admin/config.php" ]];then
    mb_dir="$(ls -1 */admin/config.php 2>/dev/null|awk -F'/' '{print $1}')"
    if [[ -d "$mb_dir" ]];then
        rsync -aq $doc_root/$mb_dir/ $doc_root/
        rm -rf $doc_root/$mb_dir
    else
        echo -e "Could not identify the directory containing the extracted install files. Something may have gone wrong with the ZIP file extraction.\nExiting...\n"
        exit 1
    fi
    getSqlSchema
else
    echo -e "Could not locate config file. Something may have gone wrong with the ZIP file extraction.\nExiting...\n"
    exit 1
fi

# Set  file permissions and ownership.
chown -R $c_uid.$c_uid *
chgrp -R nobody media cache
chmod -R 777 csv_photos media cache ftp_content content admin/scripts admin/logs 2>/dev/null

# Create MySQL db, import schema, perform site setup and create admin user.
mysql $reqPass -e "create database $mysqlDb;"
mysql $reqPass -e "grant all on $mysqlDb.* to $mysqlUser@localhost identified by '$mysqlPass';"
mysql $reqPass -e "flush privileges;"
mysql $reqPass $mysqlDb < "$mb_sql"

# Update config.php.
sed -i.$date \
    -e "s/^\$dbname.*/\$dbname = '$mysqlDb';/" \
    -e "s/^\$dbuser.*/\$dbuser = '$mysqlUser';/" \
    -e "s/^\$dbpass.*/\$dbpass = '$mysqlPass';/" \
    -e "s/^\$admin_username.*/\$admin_username = '$admin_user';/" \
    -e "s/^\$admin_password.*/\$admin_password = '$admin_pass';/" \
    -e "s/^\$admin_email.*/\$admin_email = '$admin_email';/" \
    -e "s~^\$basepath.*~\$basepath = '$doc_root';~" \
    -e "s~^\$basehttp.*~\$basehttp = 'http://$domain';~" \
    -e "s/^\$mediadomain.*/\$mediadomain = 'media.$domain';/" admin/config.php

if [[ -n "$mb_license" ]];then
    sed -i "s/^\$licenseKey.*/\$licenseKey = \"$mb_license\";/" admin/config.php
else
    nolicense=1
fi

printf "\n\033[1;32mMechBunny is installed on $domain!\033[0m\n"

tput bold
printf "\nHere are the credentials (also appended to /root/mechbunny_logins.txt):\n"
tput sgr0

printf "\033[1;32mhttp://$domain/admin/login.php\nUsername: $admin_user\nPassword: $admin_pass\033[0m\n"

printf "http://$domain/admin/login.php\nUsername: $admin_user\nPassword: $admin_pass\n\n" >> /root/mechbunny_logins.txt

printf "\nReminder: Add the media.$domain entry in lighttpd and DNS. Something like:\n"

tput bold
printf "\n\$HTTP[\"host\"] == \"media.$domain\" {\n    server.document-root = \"$doc_root/media\"\n}\n\n"
tput sgr0

# Check PHP version.
php_version=`php -v|head -1|awk '{print $2}'|awk -F'.' '{print $1"."$2}'`
if [[ "$(echo $php_version '>=' 5.2|bc -l)" == 0 ]];then
    echo -ne "\033[1;31mWarning:\033[0m PHP is at version $php_version, please update to 5.2 or later.\n"
fi

# Check for other MechBunny requirements, alert if missing.
if ! which convert >/dev/null 2>&1;then
    printf "\033[1;31mImageMagick not found.\033[0m Please install.\n"
fi

if ! which ffmpeg >/dev/null 2>&1;then
    printf "\033[1;31mffmpeg not found.\033[0m Please install.\n"
fi

if ! which yamdi >/dev/null 2>&1;then
    printf "\033[1;31myamdi not found.\033[0m Please install.\n\n"
fi

if [[ "$licensed_version" -eq 1 ]];then
    if ! grep -i ioncube $php_ini_path >/dev/null 2>&1;then
        echo printf "\033[1;31mIonCube Loader not found in $php_ini_path.\033[0m Please install.\n\n"
    fi
    if [[ -n "$nolicense" ]];then
        printf "\033[1;31mUpdate license code in admin/config.php if needed!\033[0m\n"
    fi
fi

exit 0
